﻿using YeqianFramework;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using YeqianFramework.core;
using Assets.Scripts.config;
using YeqianFramework.common;
using System.Text;
using System;

namespace Assets.Scripts
{
	[RequireComponent(typeof(Rigidbody))]
	public abstract class Star : MonoBehaviour
	{
		/// <summary>
		/// 除了自己之外的天体的刚体
		/// </summary>
		protected List<Rigidbody> rigidbodies = new List<Rigidbody>();
		/// <summary>
		/// 自己到各个天体之间的距离
		/// </summary>
		protected List<float> distances = new List<float>();
		/// <summary>
		/// 1 / distance^2
		/// </summary>
		protected List<float> oneDivideDistancePower2 = new List<float>();

		#region 共通天体数据
		[SerializeField]
		protected Rigidbody m_Rigidbody;
		[SerializeField]
		protected float speed;
		[SerializeField]
		protected float forceScale = 1;
		#endregion

		#region Debug用
		/// <summary>
		/// Scene 视图中绘制力，放大几倍
		/// </summary>
		[Header("Debug 用"), SerializeField]
		protected float froce = 1;
		/// <summary>
		/// Scene 视图中绘制速度，放大几倍
		/// </summary>
		[SerializeField]
		protected float velocityScale = 1;
		#endregion

		protected void Awake()
		{
			m_Rigidbody = GetComponent<Rigidbody>();
			m_Rigidbody.constraints = RigidbodyConstraints.FreezePositionZ;
			InitStarData();

			var temp = FindObjectsOfType<Rigidbody>().ToList();
			float dist;
			foreach (var item in temp)
			{
				if (item.gameObject != gameObject)
				{
					rigidbodies.Add(item);
					dist = Vector3.Distance(transform.position, item.position);
					distances.Add(dist);
					oneDivideDistancePower2.Add(1 / Mathf.Pow(dist, 2));
				}
			}

			Vector3 v = new Vector3(UnityEngine.Random.Range(-1.0f, 1), UnityEngine.Random.Range(-1.0f, 1), UnityEngine.Random.Range(-1.0f, 1));
			m_Rigidbody.useGravity = false;
			m_Rigidbody.velocity = v.normalized * speed;

		}

		/// <summary>
		/// 加载该加载的数据
		/// </summary>
		protected abstract void InitStarData();

		protected virtual void FixedUpdate()
		{
			UpdateDistance();

			Vector3 resultantForce = Vector3.zero;
			Vector3 temp;
			for (int i = 0; i < rigidbodies.Count; i++)
			{
				if (!rigidbodies[i].gameObject.activeInHierarchy) continue;

				temp = CalculateFroce(rigidbodies[i].position, rigidbodies[i], oneDivideDistancePower2[i]);
				resultantForce += temp;
				Debug.DrawRay(transform.position, temp * froce);
			}

			Debug.DrawRay(transform.position, m_Rigidbody.velocity * velocityScale, Color.red);
			m_Rigidbody.AddForce(resultantForce);
		}

		private void UpdateDistance()
		{
			for (int i = 0; i < rigidbodies.Count; i++)
			{
				distances[i] = Vector3.Distance(transform.position, rigidbodies[i].position);
				oneDivideDistancePower2[i] = 1 / Mathf.Pow(distances[i], 2);
			}
		}

		private Vector3 CalculateFroce(Vector3 targetPosition, Rigidbody tagretRigidbody, float local_1divideDisPower2)
		{
			return (targetPosition - transform.position).normalized * local_1divideDisPower2 * forceScale * m_Rigidbody.mass * tagretRigidbody.mass;
		}

		[SerializeField]
		private bool isDestorySelfOnCollisionEnter = true;
		protected virtual void OnCollisionEnter(Collision collision)
		{
			Debug.Log(string.Format("{0} 与 {1} 相撞", gameObject.name, collision.gameObject.name));
			MessageCenter.Current.SendMyMessage("star2star", null);
			if (isDestorySelfOnCollisionEnter) gameObject.SetActive(false);
		}
	}
}
